package cc.shacocloud.mirage.utils.converter;

import cc.shacocloud.mirage.utils.ClassUtil;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * 类型不匹配异常
 *
 * @author 思追(shaco)
 */
public class TypeMismatchException extends RuntimeException {
    
    @Getter
    @Nullable
    private final transient Object value;
    
    @Getter
    @Nullable
    private final Class<?> requiredType;
    
    /**
     * 创建一个新的 {@code TypeMismatchException}
     *
     * @param value        无法转换的违规值（可能是 {@code null}）
     * @param requiredType 所需的目标类型（如果未知，则为 {@code null}）
     */
    public TypeMismatchException(@Nullable Object value, @Nullable Class<?> requiredType) {
        this(value, requiredType, null);
    }
    
    /**
     * 创建一个新的 {@code TypeMismatchException}，而不带 {@code PropertyChangeEvent}。
     *
     * @param value        无法转换的违规值（可能是 {@code null}）
     * @param requiredType 所需的目标类型（如果未知，则为 {@code null}）
     * @param cause        根本原因（可能是 {@code 空}）
     */
    public TypeMismatchException(@Nullable Object value, @Nullable Class<?> requiredType, @Nullable Throwable cause) {
        this(value, requiredType, "无法转换类型的值 '" + ClassUtil.getDescriptiveType(value) + "'"
                + (requiredType != null ? " 到所需类型 '" + requiredType.getTypeName() + "'" : ""), cause);
    }
    
    /**
     * 创建一个新的 {@code TypeMismatchException}，而不带 {@code PropertyChangeEvent}。
     *
     * @param value        无法转换的违规值（可能是 {@code null}）
     * @param requiredType 所需的目标类型（如果未知，则为 {@code null}）
     * @param message      异常消息
     * @param cause        根本原因（可能是 {@code 空}）
     */
    public TypeMismatchException(@Nullable Object value,
                                 @Nullable Class<?> requiredType,
                                 @NotNull String message,
                                 @Nullable Throwable cause) {
        super(message, cause);
        this.value = value;
        this.requiredType = requiredType;
    }
    
}
